/**
 * WebSocket连接池适配器
 * 将现有的WebSocket服务与新的连接池系统整合
 */

import { globalWebSocketPool, ConnectionState, type WebSocketConfig } from '@/utils/websocket-pool';
import type { DataSource, WSMessage, WSConnection } from './websocket';

export interface PooledDataSource extends DataSource {
  poolConnectionId?: string; // 对应连接池中的连接ID
  poolEnabled?: boolean; // 是否使用连接池
}

/**
 * WebSocket连接池适配器类
 */
export class WebSocketPoolAdapter {
  private dataSourceConnections = new Map<string, string>(); // dataSourceId -> poolConnectionId
  private connectionDataSources = new Map<string, string>(); // poolConnectionId -> dataSourceId
  private messageHandlers: ((message: WSMessage, sourceId: string) => void)[] = [];

  constructor() {
    // 注册连接池消息处理器
    globalWebSocketPool.addMessageHandler(this.handlePoolMessage.bind(this));

    // 注册连接池状态变化处理器
    globalWebSocketPool.addStateChangeHandler(this.handleStateChange.bind(this));
  }

  /**
   * 连接到数据源（使用连接池）
   */
  async connectToDataSource(dataSource: PooledDataSource): Promise<void> {
    if (!dataSource.poolEnabled) {
      throw new Error('数据源未启用连接池模式');
    }

    // 检查是否已经有连接
    if (this.dataSourceConnections.has(dataSource.id)) {
      console.log(`数据源 ${dataSource.name} 已有连接池连接`);
      return;
    }

    const config: WebSocketConfig = {
      url: dataSource.url,
      reconnectInterval: 3000,
      maxReconnectAttempts: 5,
      heartbeatInterval: 30000,
      connectionTimeout: 10000,
      maxMessageQueueSize: 100
    };

    try {
      const connectionId = await globalWebSocketPool.createConnection(config);

      // 建立映射关系
      this.dataSourceConnections.set(dataSource.id, connectionId);
      this.connectionDataSources.set(connectionId, dataSource.id);

      console.log(`数据源 ${dataSource.name} 成功连接到连接池 (${connectionId})`);

      // 订阅数据（如果需要）
      this.subscribeToDataSource(dataSource.id);
    } catch (error) {
      console.error(`连接到数据源 ${dataSource.name} 失败:`, error);
      throw error;
    }
  }

  /**
   * 断开数据源连接
   */
  disconnectFromDataSource(dataSourceId: string): void {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) {
      console.warn(`数据源 ${dataSourceId} 没有找到对应的连接池连接`);
      return;
    }

    // 关闭连接
    globalWebSocketPool.closeConnection(connectionId);

    // 清理映射关系
    this.dataSourceConnections.delete(dataSourceId);
    this.connectionDataSources.delete(connectionId);

    console.log(`数据源 ${dataSourceId} 已从连接池断开`);
  }

  /**
   * 订阅数据源
   */
  private subscribeToDataSource(dataSourceId: string): void {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) return;

    // 发送订阅消息（根据具体协议调整）
    const subscribeMessage = {
      type: 'subscribe',
      sourceId: dataSourceId,
      timestamp: Date.now()
    };

    globalWebSocketPool.sendMessage(connectionId, subscribeMessage);
  }

  /**
   * 发送消息到特定数据源
   */
  sendToDataSource(dataSourceId: string, message: any): boolean {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) {
      console.warn(`数据源 ${dataSourceId} 未连接`);
      return false;
    }

    return globalWebSocketPool.sendMessage(connectionId, {
      ...message,
      sourceId: dataSourceId,
      timestamp: Date.now()
    });
  }

  /**
   * 广播消息到所有连接的数据源
   */
  broadcastToAllSources(message: any): number {
    return globalWebSocketPool.broadcast({
      ...message,
      timestamp: Date.now()
    });
  }

  /**
   * 处理连接池消息
   */
  private handlePoolMessage(data: any, connectionId: string): void {
    // 获取对应的数据源ID
    const dataSourceId = this.connectionDataSources.get(connectionId);
    if (!dataSourceId) {
      console.warn(`收到未知连接的消息: ${connectionId}`);
      return;
    }

    // 构造WSMessage
    const message: WSMessage = {
      type: data.type || 'data',
      data: data.data || data,
      timestamp: data.timestamp || Date.now(),
      source: dataSourceId
    };

    // 调用消息处理器
    this.messageHandlers.forEach((handler) => {
      try {
        handler(message, dataSourceId);
      } catch (error) {
        console.error('消息处理器执行失败:', error);
      }
    });
  }

  /**
   * 处理连接状态变化
   */
  private handleStateChange(connectionId: string, state: ConnectionState): void {
    const dataSourceId = this.connectionDataSources.get(connectionId);
    if (!dataSourceId) return;

    console.log(`数据源 ${dataSourceId} 连接状态变化: ${state}`);

    // 可以在这里触发状态变化事件
    // 例如更新UI状态、重新订阅等
  }

  /**
   * 添加消息处理器
   */
  addMessageHandler(handler: (message: WSMessage, sourceId: string) => void): void {
    this.messageHandlers.push(handler);
  }

  /**
   * 移除消息处理器
   */
  removeMessageHandler(handler: (message: WSMessage, sourceId: string) => void): void {
    const index = this.messageHandlers.indexOf(handler);
    if (index > -1) {
      this.messageHandlers.splice(index, 1);
    }
  }

  /**
   * 获取数据源连接状态
   */
  getDataSourceStatus(dataSourceId: string): WSConnection | null {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) return null;

    const connections = globalWebSocketPool.getConnectionDetails();
    const connectionInfo = connections.find((c) => c.id === connectionId);

    if (!connectionInfo) return null;

    // 转换为WSConnection格式
    return {
      id: dataSourceId,
      name: `数据源-${dataSourceId}`,
      url: connectionInfo.url,
      ws: connectionInfo.websocket as WebSocket,
      status: this.convertConnectionState(connectionInfo.state),
      lastHeartbeat: connectionInfo.lastPing,
      reconnectAttempts: connectionInfo.reconnectAttempts,
      reconnectTimer: null, // 连接池管理，不暴露
      heartbeatTimer: null // 连接池管理，不暴露
    };
  }

  /**
   * 转换连接状态
   */
  private convertConnectionState(
    state: ConnectionState
  ): 'disconnected' | 'connecting' | 'connected' | 'error' {
    switch (state) {
      case ConnectionState.CONNECTED:
        return 'connected';
      case ConnectionState.CONNECTING:
      case ConnectionState.RECONNECTING:
        return 'connecting';
      case ConnectionState.FAILED:
        return 'error';
      default:
        return 'disconnected';
    }
  }

  /**
   * 获取所有数据源状态
   */
  getAllDataSourceStatuses(): WSConnection[] {
    const statuses: WSConnection[] = [];

    for (const dataSourceId of this.dataSourceConnections.keys()) {
      const status = this.getDataSourceStatus(dataSourceId);
      if (status) {
        statuses.push(status);
      }
    }

    return statuses;
  }

  /**
   * 获取连接池统计信息
   */
  getPoolStatistics() {
    const poolStats = globalWebSocketPool.getPoolStats();
    const connectionDetails = globalWebSocketPool.getConnectionDetails();

    return {
      pool: poolStats,
      connections: connectionDetails.map((conn) => ({
        id: conn.id,
        url: conn.url,
        state: conn.state,
        dataSourceId: this.connectionDataSources.get(conn.id),
        messagesSent: conn.messagesSent,
        messagesReceived: conn.messagesReceived,
        queuedMessages: conn.messageQueue.length,
        lastConnected: conn.lastConnected,
        reconnectAttempts: conn.reconnectAttempts
      }))
    };
  }

  /**
   * 平滑切换：从传统连接切换到连接池
   */
  async migrateToPool(
    dataSources: PooledDataSource[],
    legacyConnections: WSConnection[]
  ): Promise<void> {
    console.log('开始迁移到连接池模式...');

    for (const dataSource of dataSources) {
      if (!dataSource.poolEnabled) continue;

      try {
        // 查找对应的传统连接
        const legacyConnection = legacyConnections.find(
          (conn) => conn.url === dataSource.url || conn.id === dataSource.id
        );

        // 先建立连接池连接
        await this.connectToDataSource(dataSource);

        // 如果有传统连接，等待稳定后再关闭
        if (legacyConnection && legacyConnection.ws) {
          setTimeout(() => {
            legacyConnection.ws?.close();
            console.log(`关闭传统连接: ${legacyConnection.name}`);
          }, 2000); // 等待2秒确保连接池连接稳定
        }

        console.log(`数据源 ${dataSource.name} 迁移完成`);
      } catch (error) {
        console.error(`数据源 ${dataSource.name} 迁移失败:`, error);
      }
    }

    console.log('连接池迁移完成');
  }

  /**
   * 健康检查
   */
  performHealthCheck(): {
    healthyConnections: number;
    totalConnections: number;
    issues: string[];
  } {
    const stats = globalWebSocketPool.getPoolStats();
    const issues: string[] = [];

    // 检查连接健康状况
    if (stats.failedCount > 0) {
      issues.push(`有 ${stats.failedCount} 个连接处于失败状态`);
    }

    if (stats.reconnectingCount > 0) {
      issues.push(`有 ${stats.reconnectingCount} 个连接正在重连`);
    }

    if (stats.queuedMessages > 50) {
      issues.push(`消息队列积压过多: ${stats.queuedMessages} 条消息`);
    }

    // 检查负载均衡情况
    const connections = globalWebSocketPool.getConnectionDetails();
    const activeConnections = connections.filter((c) => c.state === ConnectionState.CONNECTED);

    if (activeConnections.length > 0) {
      const avgSubscribers =
        activeConnections.reduce((sum, c) => sum + c.activeSubscribers, 0) /
        activeConnections.length;
      const imbalanced = activeConnections.some(
        (c) => Math.abs(c.activeSubscribers - avgSubscribers) > avgSubscribers * 0.5
      );

      if (imbalanced) {
        issues.push('连接负载不均衡');
      }
    }

    return {
      healthyConnections: stats.connectedCount,
      totalConnections: stats.totalConnections,
      issues
    };
  }

  /**
   * 销毁适配器
   */
  destroy(): void {
    // 断开所有数据源连接
    for (const dataSourceId of this.dataSourceConnections.keys()) {
      this.disconnectFromDataSource(dataSourceId);
    }

    // 清理处理器
    this.messageHandlers = [];

    console.log('WebSocket连接池适配器已销毁');
  }
}

// 全局适配器实例
export const globalWSPoolAdapter = new WebSocketPoolAdapter();
